package com.bckj.fastboot.core.extra.datascope.handler;

import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
import com.bckj.fastboot.core.extra.datascope.DataFilterThreadLocal;
import com.bckj.fastboot.core.extra.datascope.model.DataScope;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.HexValue;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.schema.Column;

import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class MyDataScopeHandler implements DataPermissionHandler {

    @Override
    public Expression getSqlSegment(Expression where, String mappedStatementId) {
        DataScope localDataScope = DataFilterThreadLocal.get();
        if (localDataScope == null) {
            return where;
        }
        log.debug("开始进行权限过滤,dataScope:{} , where: {},mappedStatementId: {}", localDataScope, where, mappedStatementId);
        try {
            if (where == null) {
                where = new HexValue(" 1 = 1 ");
            }
            switch (localDataScope.getDataScopeType()) {
                case "2" -> {
                    EqualsTo equalsTo = new EqualsTo();
                    equalsTo.setLeftExpression(new Column(localDataScope.getScopeName()));
                    equalsTo.setRightExpression(new LongValue(localDataScope.getDeptId()));
                    return new AndExpression(where, equalsTo);
                }
                case "3" -> {
                    EqualsTo selfEqualsTo = new EqualsTo();
                    selfEqualsTo.setLeftExpression(new Column("create_by"));
                    selfEqualsTo.setRightExpression(new LongValue(localDataScope.getUserId()));
                    return new AndExpression(where, selfEqualsTo);
                }
                case "4" -> {
                    Set<Long> deptIds = localDataScope.getDeptIds();
                    ExpressionList<LongValue> itemsList = new ExpressionList<>(deptIds.stream().map(LongValue::new).collect(Collectors.toList()));
                    InExpression inExpression = new InExpression(new Column(localDataScope.getScopeName()), itemsList);
                    return new AndExpression(where, inExpression);
                }
                default -> {
                    return where;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            DataFilterThreadLocal.clear();
        }
        return null;
    }
}
